/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.edu.unal.ahnmodeler.controller;

import co.edu.unal.ahnmodeler.main.App;
import co.edu.unal.ahnmodeler.model.Connection;
import co.edu.unal.ahnmodeler.model.Network;
import co.edu.unal.ahnmodeler.model.Node;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Clase que se encarga de realizar todas las funcionalidades relacionadas con el manejo de los componentes de la red Ad-Hoc.
 * @author Phelipe
 */
public class NetworkController {
    private static NetworkController INSTANCE = null;
    
    // creador sincronizado para protegerse de posibles problemas  multi-hilo
    // otra prueba para evitar instanciación múltiple 
    private synchronized static void createInstance() {
        if (INSTANCE == null) { 
            INSTANCE = new NetworkController();
        }
    }
 
    /**
     * Permite retornar la instancia del controlador de la red Ad-Hoc.
     * @return Instancia del controlador de la red Ad-Hoc
     */
    public static NetworkController getInstance() {
        createInstance();
        return INSTANCE;
    }
    
    private NetworkController(){  
        System.out.println("Clase NetworkController");
        network = Network.getInstance();
    }
    
    /**
     * Genera la red Ad-Hoc a partir de los nodos que se reciben como parámetro
     * @param nNodos Nodos que conforman la red Ad-Hoc
     */
    public void genNetwork(int nNodos){
        for (int i = 0; i < nNodos; i++) {
            this.addNode();
        }
    }
    
    /**
     * Inicia el proceso de simulación.
     */
    public void startSimulation(){
        network.startSimulation();
    }
    
    /**
     * Detiene la simulación que está en ejecución
     */
    public void stopSimulation(){
        network.stopSimulation();
    }
    
    /**
     * Elimina la red Ad-Hoc actual y si existe una simulación en ejcución la detiene.
     */
    public void deleteNetwork(){
        network.deleteNetwork();
        App.getmFrame().getpModel().repaint();
    }

    /**
     * Agrega un nuevo nodo a la red Ad-Hoc.
     * Inicia un hilo que le permite moverse a través de la red e interactuar con otros nodos.
     * Se dibuja el componente gráfico que representa el nodo en el modelo de la red Ad-Hoc.
     */
    public void addNode() {
        network.addNode();
        App.getmFrame().getpModel().repaint();
    }

    /**
     * Elimina el nodo de la red Ad-Hoc que se recibe como parámetro.
     * Detiene el hilo del nodo.
     * Se elimina el componente gráfico que representa el nodo en el modelo de la red Ad-Hoc.
     * @param node Nodo a eliminar en la red Ad-Hoc.
     */
    public void deleteNode(Node node){
        network.deleteNode(node);
        App.getmFrame().getpModel().repaint();
    }
    
    /**
     * Elimina aleatoriamente un nodo en la red Ad-Hoc.
     * Detiene el hilo del nodo.
     * Se elimina el componente gráfico que representa el nodo en el modelo de la red Ad-Hoc.
     */
    public void deleteNode() {
        network.deleteNode();
        App.getmFrame().getpModel().repaint();
    }

    /**
     * Deselecciona todos los nodos que esten seleccionados en la red Ad-hoc.
     */
    public void deselectNode() {
        network.deselectNode();
    }

    /**
     * Permite obtener todos los nodos de la red Ad-hoc en un instante de tiempo determinado.
     * @return Conjunto de nodos que conforman la red Ad-Hoc.
     */
    public CopyOnWriteArrayList<Node> getNodes() {
        return network.getNodes();
    }

    /**
     * Permite realizar y eliminar las conexiones entre los nodos en la red Ad-Hoc en un instante de tiempo determinado.
     */
    public void addConnetions() {
        network.addConnetions();
    }

    /**
     * Permite repintar el modelo gráfico de la red Ad-Hoc.
     */
    public void updateModel() {
        App.getmFrame().getpModel().repaint();
    }

    /**
     * Permite obtener la lista de las conexiones existentes entre los nodos que conforman la red Ad-Hoc en un instante de tiempo determinado.
     * @return Lista de las conexiones entre los nodos de la red Ad-Hoc.
     */
    public CopyOnWriteArrayList<Connection> getConnections() {
        return network.getConnections();
    }
    
    private Network network;
}
